#include "SchedulerInc.h"

using namespace bimar_scheduler_lib;

CJobExecutor::CJobExecutor()
:CGThreadWrapper("CJobExecutor")
,m_currentScheduler(NULL)
,m_currentJob(NULL)
{
  CreateThread();
}

CJobExecutor::~CJobExecutor()
{
  DestroyScheduler();
}

gboolean CJobExecutor::StartJob(CJob *job)
{  
  return CreateScheduler(job);
}

gboolean CJobExecutor::ResumeCurrentJob()
{
  if(IsIdle())
    return FALSE;

  return m_currentScheduler->Resume();
}

gboolean CJobExecutor::PauseCurrentJob()
{
  if(IsIdle())
    return FALSE;

  return m_currentScheduler->Pause();
}

gboolean CJobExecutor::AbortCurrentJob()
{
  if(IsIdle())
    return FALSE;

  gboolean ret = m_currentScheduler->Abort();
  DestroyScheduler(); /* to idle state */

  return ret;
}

gboolean CJobExecutor::StopCurrentJob()
{
  if(IsIdle())
    return FALSE;

  return m_currentScheduler->Stop();
}

gboolean CJobExecutor::WaitJobDone(gulong milis /*= WAIT_INFINITE*/)
{
  gboolean timeout = FALSE;  
  GTimer *timer = NULL;
  if(milis != WAIT_INFINITE)
  {
	timer = g_timer_new();
	g_timer_start(timer);
  }

  while(!IsIdle() && !timeout)
  {
	if(milis != WAIT_INFINITE)
	  timeout = (g_timer_elapsed(timer, NULL) * 1000 >= milis);

    g_thread_yield();
  }

  return !timeout;
}

gboolean CJobExecutor::CreateScheduler(CJob *job)
{
  g_return_val_if_fail(job && IsIdle(), FALSE);

  CGAutoLock lock(&m_currentJobCS);

  m_currentScheduler = new CJobScheduler(FALSE);
  m_currentJob = job;

  return TRUE;
}

gboolean CJobExecutor::DestroyScheduler()
{
  CGAutoLock lock(&m_currentJobCS);

  if(IsIdle())
    return TRUE;  

  if(m_currentScheduler)
    delete m_currentScheduler;
  m_currentScheduler = NULL;
  m_currentJob = NULL;

  return TRUE;
}

gulong CJobExecutor::RunThread()
{
  while(m_running)
  {
    if(m_currentScheduler && m_currentJob)
	{
      /* Add the Job */
	  m_currentScheduler->PushBack(m_currentJob);

	  /* Crete the ThreadPool */
	  m_currentScheduler->Create();

	  /* run the job and wait completion */
	  if(m_currentScheduler->Start())
	    m_currentScheduler->WaitJobDone();

	  /* destroy scheduler.. idle state */
	  DestroyScheduler();
	}

    g_thread_yield();
  }

  return 0;
}

gboolean CJobExecutor::IsIdle()
{
  return (m_currentScheduler == NULL);
}
